#ifndef __EVENT_DRIVER_H__
#define __EVENT_DRIVER_H__

#include <atomic>
#include <functional>
#include <mutex>
#include <thread>

#include "queue/priority_queue.h"

enum class EventPriority
{
    High,
    Medium,
    Low
};

using EventHandler = std::function<void()>;
class Event
{
  public:
    Event(const EventPriority rhsPriroty, EventHandler&& rhsHandler)
        : priority(rhsPriroty), handler(std::move(rhsHandler))
    {
    }

    EventPriority getPriority() const { return priority; }

  private:
    EventPriority priority;
    EventHandler handler;

    friend class Scheduler;
};

class EventCompare
{
  public:
    bool operator()(const Event& a, const Event& b) { return a.getPriority() > b.getPriority(); }
};

class Scheduler
{
  public:
    Scheduler() = default;

    ~Scheduler() { stop(); }

    void start();

    void stop();

    void postEvent(Event&&);

  private:
    void eventLoop();

    PriorityQueue<Event, EventCompare> events;
    std::mutex mtx;
    std::atomic<bool> running{false};
    std::thread eventThread;
};

#endif  //__EVENT_DRIVER_H__